import os
import shutil
import logging
from pathlib import Path


def sync_files(from_url, to_url, level=4,check_mtime=False):
    """
    同步源文件夹到目标文件夹

    参数:
        from_url (str): 源文件夹路径
        to_url (str): 目标文件夹路径
        level (int): 向下处理的文件夹层数，默认为4层
    """
    # 设置日志
    logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(levelname)s - %(message)s')
    logger = logging.getLogger(__name__)

    # 验证源文件夹是否存在
    if not os.path.exists(from_url):
        logger.error(f"源文件夹不存在: {from_url}")
        return False

    # 创建目标文件夹（如果不存在）
    os.makedirs(to_url, exist_ok=True)

    try:
        # 开始同步
        _sync_directory(from_url, to_url, level, 0, logger,check_mtime)
        logger.info("文件同步完成")
        return True
    except Exception as e:
        logger.error(f"同步过程中发生错误: {str(e)}")
        return False


def _sync_directory(from_dir, to_dir, max_level, current_level, logger,check_mtime):
    """
    递归同步目录

    参数:
        from_dir (str): 源目录
        to_dir (str): 目标目录
        max_level (int): 最大递归层数
        current_level (int): 当前递归层数
        logger: 日志记录器
    """
    # 如果当前层数超过最大层数，则停止递归
    if current_level >= max_level:
        logger.debug(f"达到最大递归层数 {max_level}, 停止处理: {from_dir}")
        return

    # 确保目标目录存在
    os.makedirs(to_dir, exist_ok=True)

    # 遍历源目录中的所有项目
    for item_name in os.listdir(from_dir):
        from_path = os.path.join(from_dir, item_name)
        to_path = os.path.join(to_dir, item_name)

        # 如果是文件
        if os.path.isfile(from_path):
            _sync_file(from_path, to_path, logger,check_mtime)

        # 如果是目录且未达到最大递归层数
        elif os.path.isdir(from_path):
            _sync_directory(from_path, to_path, max_level, current_level + 1, logger,check_mtime)


def _sync_file(from_file, to_file, logger,check_mtime):
    """
    同步单个文件

    参数:
        from_file (str): 源文件路径
        to_file (str): 目标文件路径
        logger: 日志记录器
    """
    # 如果目标文件不存在，直接复制
    if not os.path.exists(to_file):
        shutil.copy2(from_file, to_file)
        logger.info(f"复制新文件: {from_file} -> {to_file}")
        return

    # 获取文件大小
    from_size = os.path.getsize(from_file)
    to_size = os.path.getsize(to_file)

    # 如果文件大小不一致，以源文件为准
    if from_size != to_size:
        shutil.copy2(from_file, to_file)
        logger.info(f"更新文件(大小不一致): {from_file} -> {to_file}")
    else:
        if check_mtime:
            from_time = os.path.getmtime(from_file)
            to_time = os.path.getmtime(to_file)
            if from_time != to_time:
                shutil.copy2(from_file, to_file)
                logger.info(f"更新文件(大小不一致): {from_file} -> {to_file}")
            else:
                logger.debug(f"文件已同步(大小相同): {from_file}")
        else:
            logger.debug(f"文件已同步(大小相同): {from_file}")


def sync_files_with_progress(from_url, to_url, level=4,check_mtime=False):
    """
    带进度显示的同步文件功能

    参数:
        from_url (str): 源文件夹路径
        to_url (str): 目标文件夹路径
        level (int): 向下处理的文件夹层数，默认为4层
    """
    # 统计信息
    stats = {
        'files_copied': 0,
        'files_updated': 0,
        'files_skipped': 0,
        'directories_created': 0
    }

    def _sync_with_stats(from_dir, to_dir, max_level, current_level,check_mtime):
        """带统计的递归同步"""
        if current_level >= max_level:
            return

        # 创建目标目录
        if not os.path.exists(to_dir):
            os.makedirs(to_dir)
            stats['directories_created'] += 1

        # 遍历源目录
        for item_name in os.listdir(from_dir):
            from_path = os.path.join(from_dir, item_name)
            to_path = os.path.join(to_dir, item_name)

            if os.path.isfile(from_path):
                # 同步文件
                if not os.path.exists(to_path):
                    shutil.copy2(from_path, to_path)
                    stats['files_copied'] += 1
                    print(f"✓ 复制: {os.path.basename(from_path)}")
                else:
                    from_size = os.path.getsize(from_path)
                    to_size = os.path.getsize(to_path)
                    if from_size != to_size:
                        shutil.copy2(from_path, to_path)
                        stats['files_updated'] += 1
                        print(f"↻ 大小不一致：更新: {os.path.basename(from_path)}")
                    else:
                        if check_mtime:
                            from_time=os.path.getmtime(from_path)
                            to_time = os.path.getmtime(to_path)
                            if from_time!=to_time:
                                shutil.copy2(from_path, to_path)
                                stats['files_updated'] += 1
                                print(f"↻ 时间不一致：更新: {os.path.basename(from_path)}")
                            else:
                                stats['files_skipped'] += 1
                        else:
                            stats['files_skipped'] += 1

            elif os.path.isdir(from_path):
                _sync_with_stats(from_path, to_path, max_level, current_level + 1,check_mtime)

    # 执行同步
    if not os.path.exists(from_url):
        print(f"错误: 源文件夹不存在: {from_url}")
        return False

    print(f"开始同步: {from_url} -> {to_url}")
    print(f"递归层数: {level}")
    print("-" * 50)

    try:
        _sync_with_stats(from_url, to_url, level, 0,check_mtime)

        # 显示统计结果
        print("-" * 50)
        print("同步完成!")
        print(f"新建目录: {stats['directories_created']}")
        print(f"复制文件: {stats['files_copied']}")
        print(f"更新文件: {stats['files_updated']}")
        print(f"跳过文件: {stats['files_skipped']}")

        return True
    except Exception as e:
        print(f"同步失败: {str(e)}")
        return False


# 使用示例
if __name__ == "__main__":
    # 基本用法
    from_folder = "/path/to/source/folder"
    to_folder = "/path/to/destination/folder"

    # 方法1: 简单同步
    sync_files(from_folder, to_folder, level=4)

    # 方法2: 带进度显示的同步
    sync_files_with_progress(from_folder, to_folder, level=4)

    # 示例用法
    # sync_folders("./source", "./backup", level=3)
    # sync_folders_with_progress("./documents", "./backup_documents", level=2)